import { Graph, Shape } from "@antv/x6";
import { Stencil } from "@antv/x6-plugin-stencil"; // 左侧组件面板插件
import { Transform } from "@antv/x6-plugin-transform"; // 节点变换（缩放/旋转）插件
import { Selection } from "@antv/x6-plugin-selection"; // 选择插件（支持框选）
import { Snapline } from "@antv/x6-plugin-snapline"; // 对齐参考线插件
import { Keyboard } from "@antv/x6-plugin-keyboard"; // 键盘快捷键插件
import { Clipboard } from "@antv/x6-plugin-clipboard"; // 剪贴板插件（复制/粘贴）
import { History } from "@antv/x6-plugin-history"; // 历史记录插件（撤销/重做）

/**
 * 初始化流程图编辑器
 * @param dom 挂载画布的DOM元素
 * @returns 初始化后的Graph实例
 */
const initGraph = (dom: HTMLElement)=> {

// #region 初始化画布
// 创建Graph实例，配置画布基础属性
const graph = new Graph({
  container: dom,  // 挂载容器
  width: dom.offsetWidth, // 宽度（与容器一致）
  height: dom.offsetHeight, // 高度（与容器一致）
  grid: true, // 显示网格
   // 鼠标滚轮配置（缩放功能）
  mousewheel: {
    enabled: true,  // 启用滚轮缩放
    zoomAtMousePosition: true, // 基于鼠标位置缩放
    modifiers: 'ctrl', // 需要配合Ctrl键使用
    minScale: 0.5,  // 最小缩放比例
    maxScale: 3, // 最大缩放比例
  },
   // 连线配置
  connecting: {
    router: 'manhattan', // 采用直角路由
    connector: {
      name: 'rounded', // 圆角连接线
      args: {
        radius: 8, // 圆角半径
      },
    },
    anchor: 'center', // 连接点为节点中心
    connectionPoint: 'anchor',  // 连接点策略
    allowBlank: false,  // 不允许连接到空白处
    snap: {
      radius: 20, // 吸附半径（像素）
    },
    // 自定义连线样式
    createEdge() {
      return new Shape.Edge({
        attrs: {
          line: {
            stroke: '#A2B1C3', // 线条颜色
            strokeWidth: 2, // 线条宽度
            targetMarker: { // 目标箭头样式
              name: 'block',
              width: 12,
              height: 8,
            },
          },
        },
        zIndex: 0, // 层级（确保连线在节点下方）
      })
    },
     // 验证连接是否有效（必须连接到连接桩）
    validateConnection({ targetMagnet }:any) {
      return !!targetMagnet
    },
  },
   // 高亮配置（连接时的视觉反馈）
  highlighting: {
    magnetAdsorbed: { // 连接桩吸附时的样式
      name: 'stroke', 
      args: {
        attrs: {
          fill: '#5F95FF',
          stroke: '#5F95FF',
        },
      },
    },
  },
})
// #endregion

// #region 使用插件（扩展画布功能）
graph
// 启用节点变换插件（支持缩放和旋转）
  .use(
    new Transform({
      resizing: true, // 允许缩放
      rotating: true, // 允许旋转
    }),
  )
   // 启用选择插件
  .use(
    new Selection({
      rubberband: true, // 允许框选
      showNodeSelectionBox: true, // 显示节点选中框
    }),
  )
  .use(new Snapline()) // 启用对齐参考线
  .use(new Keyboard()) // 启用键盘快捷键
  .use(new Clipboard()) // 启用剪贴板功能
  .use(new History()) // 启用历史记录（撤销/重做）
// #endregion

// #region 初始化左侧组件面板（Stencil）
const stencil = new Stencil({
  title: '节点选择', // 面板标题
  target: graph, // 关联的画布实例
  stencilGraphWidth: 200, // 面板中每个小画布的宽度
  stencilGraphHeight: 180, // 面板中每个小画布的高度
  collapsable: true, // 允许折叠分组
  // 面板分组配置
  groups: [
    {
      title: '基础节点', // 分组标题
      name: 'group1', // 分组标识
    },
    {
      title: '系统节点',
      name: 'group2',
      graphHeight: 250, // 该分组的画布高度
      layoutOptions: {
        rowHeight: 70, // 该分组的行高
      },
    },
  ],
  // 布局配置
  layoutOptions: {
    columns: 2, // 列数
    columnWidth: 80, // 列宽
    rowHeight: 55, // 行高
  },
})
// 将组件面板添加到页面DOM中
document.getElementById('stencil')!.appendChild(stencil.container)
// #endregion

  // #region 快捷键与事件绑定
  // 复制（Ctrl+C 或 Command+C）
graph.bindKey(['meta+c', 'ctrl+c'], () => {
  const cells = graph.getSelectedCells() // 获取选中的元素
  if (cells.length) {
    graph.copy(cells) // 复制到剪贴板
  }
  return false // 阻止默认行为
})
// 剪切（Ctrl+X 或 Command+X）
graph.bindKey(['meta+x', 'ctrl+x'], () => {
  const cells = graph.getSelectedCells()
  if (cells.length) {
    graph.cut(cells) // 剪切到剪贴板（同时删除元素）
  }
  return false
})
// 粘贴（Ctrl+V 或 Command+V）
graph.bindKey(['meta+v', 'ctrl+v'], () => {
  if (!graph.isClipboardEmpty()) { // 检查剪贴板是否有内容
    const cells = graph.paste({ offset: 32 }) // 粘贴，偏移32px避免重叠
    graph.cleanSelection() // 清除原有选择
    graph.select(cells) // 选中粘贴的元素
  }
  return false
})

// 撤销（Ctrl+Z 或 Command+Z）
graph.bindKey(['meta+z', 'ctrl+z'], () => {
  if (graph.canUndo()) { // 检查是否可以撤销
    graph.undo() // 执行撤销
  }
  return false
})
 // 重做（Ctrl+Shift+Z 或 Command+Shift+Z）
graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
  if (graph.canRedo()) { // 检查是否可以重做
    graph.redo() // 执行重做
  }
  return false
})

// 全选（Ctrl+A 或 Command+A）
graph.bindKey(['meta+a', 'ctrl+a'], () => {
  const nodes = graph.getNodes() // 获取所有节点
  if (nodes) {
    graph.select(nodes) // 选中所有节点
  }
})

//  删除（Backspace键）
graph.bindKey('backspace', () => {
  const cells = graph.getSelectedCells() // 获取选中的元素
  if (cells.length) {
    graph.removeCells(cells) // 删除选中元素
  }
})

// 放大（Ctrl+1 或 Command+1）
graph.bindKey(['ctrl+1', 'meta+1'], () => {
  const zoom = graph.zoom() // 获取当前缩放比例
  if (zoom < 1.5) { // 限制最大放大比例
    graph.zoom(0.1)// 每次放大0.1倍
  }
})
// 缩小（Ctrl+2 或 Command+2）
graph.bindKey(['ctrl+2', 'meta+2'], () => {
  const zoom = graph.zoom()
  if (zoom > 0.5) { // 限制最小缩小比例
    graph.zoom(-0.1) // 每次缩小0.1倍
  }
})

  // 控制连接桩显示/隐藏的工具函数
const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
  for (let i = 0, len = ports.length; i < len; i += 1) {
    ports[i].style.visibility = show ? 'visible' : 'hidden'
  }
}
  // 鼠标进入节点时显示连接桩
graph.on('node:mouseenter', () => {
  
  const ports = dom.querySelectorAll(
    '.x6-port-body',
  ) as NodeListOf<SVGElement>
  showPorts(ports, true)
})
  // 鼠标离开节点时隐藏连接桩
graph.on('node:mouseleave', () => {
  const ports = dom.querySelectorAll(
    '.x6-port-body',
  ) as NodeListOf<SVGElement>
  showPorts(ports, false)
})
// #endregion

  // #region 初始化自定义图形（节点类型定义）
  // 定义连接桩配置（节点上的连接点）
const ports = {
  groups: {
    top: { // 顶部连接桩
      position: 'top', 
      attrs: {
        circle: {
          r: 4, // 半径
          magnet: true, // 允许被连接
          stroke: '#5F95FF', // 边框颜色
          strokeWidth: 1,
          fill: '#fff', // 填充色
          style: {
            visibility: 'hidden', // 默认隐藏
          },
        },
      },
    },
    right: {
      position: 'right',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
    bottom: {
      position: 'bottom',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
    left: {
      position: 'left',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
  },
  // 为每个方向添加一个连接桩
  items: [
    {
      group: 'top',
    },
    {
      group: 'right',
    },
    {
      group: 'bottom',
    },
    {
      group: 'left',
    },
  ],
}
  // 注册自定义矩形节点
Graph.registerNode(
  'custom-rect', // 节点类型标识
  {
    inherit: 'rect', // 继承自基础矩形节点
    width: 66, // 宽度
    height: 36, // 高度
    attrs: { // 样式属性
      body: {
        strokeWidth: 1,
        stroke: '#5F95FF', // 边框颜色
        fill: '#EFF4FF', // 填充色
      },
      text: {
        fontSize: 12,
        fill: '#262626',
      },
    },
    ports: { ...ports }, // 应用连接桩配置
  },
  true,
)
// 注册自定义多边形节点
Graph.registerNode(
  'custom-polygon', 
  {
    inherit: 'polygon', // 继承自基础多边形节点
    width: 66,
    height: 36,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: '#5F95FF',
        fill: '#EFF4FF',
      },
      text: {
        fontSize: 12,
        fill: '#262626',
      },
    },
    ports: {
      ...ports,
      // 多边形节点只保留上下连接桩
      items: [
        {
          group: 'top',
        },
        {
          group: 'bottom',
        },
      ],
    },
  },
  true,
)
// 注册自定义圆形节点
Graph.registerNode(
  'custom-circle',
  {
    inherit: 'circle',
    width: 45,
    height: 45,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: '#5F95FF',
        fill: '#EFF4FF',
      },
      text: {
        fontSize: 12,
        fill: '#262626',
      },
    },
    ports: { ...ports },
  },
  true,
)
 // 注册带图标的自定义节点
Graph.registerNode(
  'custom-image',
  {
    inherit: 'rect',
    width: 52,
    height: 52,
     // 自定义节点结构（矩形+图片+文本）
    markup: [
      {
        tagName: 'rect',
        selector: 'body',
      },
      {
        tagName: 'image',
      },
      {
        tagName: 'text',
        selector: 'label',
      },
    ],
    attrs: {
      body: {
        stroke: '#5F95FF',
        fill: '#5F95FF',
      },
      // 图片样式
      image: {
        width: 26,
        height: 26,
        refX: 13, // X方向偏移
        refY: 16, // Y方向偏移
      },
      label: { // 文本样式
        refX: 3,
        refY: 2,
        textAnchor: 'left',
        textVerticalAnchor: 'top',
        fontSize: 12,
        fill: '#fff',
      },
    },
    ports: { ...ports },
  },
  true,
)
 // 创建基础流程图节点并添加到左侧面板
const r1 = graph.createNode({
  shape: 'custom-rect',
  label: '开始',
  attrs: {
    body: {
      rx: 20,
      ry: 26,
    },
  },
})
const r2 = graph.createNode({
  shape: 'custom-rect',
  label: '过程\n(prompt节点)',
  data:{
    type: "prompt"
  }
})
const r3 = graph.createNode({
  shape: 'custom-rect',
  attrs: {
    body: {
      rx: 6,
      ry: 6,
    },
  },
  label: '可选过程',
})
const r4 = graph.createNode({
  shape: 'custom-polygon',
  attrs: {
    body: {
      refPoints: '0,10 10,0 20,10 10,20',
    },
  },
  data:{
    type:'tool'
  },
  label: '决策',
})
const r5 = graph.createNode({
  shape: 'custom-polygon',
  attrs: {
    body: {
      refPoints: '10,0 40,0 30,20 0,20',
    },
  },
  label: '数据',
})
const r6 = graph.createNode({
  shape: 'custom-circle',
  label: '连接',
})
// 将节点添加到第一个分组
stencil.load([r1, r2, r3, r4, r5, r6], 'group1')

 // 创建带图标的系统设计节点
const imageShapes = [
  {
    label: 'Client',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/687b6cb9-4b97-42a6-96d0-34b3099133ac.svg',
  },
  {
    label: 'Http',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/dc1ced06-417d-466f-927b-b4a4d3265791.svg',
  },
  {
    label: 'Api',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg',
  },
  {
    label: 'Sql',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/6eb71764-18ed-4149-b868-53ad1542c405.svg',
  },
  {
    label: 'Clound',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/c36fe7cb-dc24-4854-aeb5-88d8dc36d52e.svg',
  },
  {
    label: 'Mq',
    image:
      'https://gw.alipayobjects.com/zos/bmw-prod/2010ac9f-40e7-49d4-8c4a-4fcf2f83033b.svg',
  },
]
const imageNodes = imageShapes.map((item) =>
  graph.createNode({
    shape: 'custom-image',
    label: item.label,
    attrs: {
      image: {
        'xlink:href': item.image,  // 设置图片URL
      },
    },
  }),
)
  // 将带图标的节点添加到第二个分组
stencil.load(imageNodes, 'group2')
// #endregion
return graph; // 返回初始化好的画布实例
}

export {
    initGraph
}